package com.hengpeng.common.scheduling;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.hengpeng.common.cis.ComponentContextLoader;
import com.hengpeng.common.configuration.CachedSystemConfig;
import com.hengpeng.common.exception.ServiceResult;
import com.hengpeng.common.persist.entity.AbstractEntity.BoolValue;
import com.hengpeng.common.scheduling.entity.SystemJob;
import com.hengpeng.common.scheduling.entity.SystemJob.SystemJobState;

public abstract class AbstractJob implements Command {
    public static final String SYSTEM_STATUS_KEYS = "SYSTEM_STATUS";// 系统状态系统参数Key值

    public static final String SYSTEM_STATUS_RUNNING = "1";// 系统正常运行

    public static final String SYSTEM_STATUS_STOP = "0";// 系统停止

    public AbstractJob() {
        this.jobSerivce = ComponentContextLoader.getBean(SystemJobService.class);
    }

    // 首次启动要检查任务状态
    private static Boolean flag = false;

    public static Log log = LogFactory.getLog(AbstractJob.class);

    @Autowired
    protected SystemJobService jobSerivce;

    private void checkSystemJob() {
        if (!flag) {
            synchronized (flag) {
                if (!flag) {
                    int num = jobSerivce.resetAllSystemJob();
                    log.info("共有[" + num + "]个任务状态被重置");
                    flag = true;
                }
            }
        }
    }

    /**
     * <pre>
     * 任务调度开始
     * </pre>
     */
    public void excute(ScheduleConfig config) throws Exception {
        // 初次启动时，把定时作业的状态全部改成 等待运行
        checkSystemJob();
        // 检查系统是否正在正常运行
        String systemStatus = CachedSystemConfig.getInstance()
                .getConfigValue(SYSTEM_STATUS_KEYS, SYSTEM_STATUS_RUNNING);
        if ("0".equalsIgnoreCase(systemStatus)) {
            return;
        }

        boolean isTimeout = false;

        SystemJob systemJob = jobSerivce.checkJob(this.getClass().getName(), config.getName(), config.getDescript());
        if (systemJob.getCanRun() == BoolValue.NO) {
            log.info(systemJob.getTaskName() + "作业的状态为{" + systemJob.getCanRun() + "},不可调度");
            return;
        }
        long timeout = config.getTimeOut();
        if ((systemJob.getRunState() == SystemJobState.RUNING) && (timeout != -1)) {
            // 如果任务正在运行,且有加入超时处理
            long runtimeNum = new Date().getTime() - systemJob.getLastStartTime().getTime();
            if (runtimeNum > timeout) {
                // 工作超时
                isTimeout = true;
            }
        }
        if (systemJob.getRunState() == SystemJobState.WAITING || isTimeout) {
            boolean isSuccess = true;
            ServiceResult<SystemJob> result = jobSerivce.execSystemJob(systemJob.getClassName(), timeout);
            if (result.getReturnValue() != null) {
                // long start = new Date().getTime();
                try {
                    exec(isTimeout, config);
                } catch (Exception ex) {
                    log.error("执行定时任务{" + systemJob.getTaskName() + "}出现异常.", ex);
                    isSuccess = false;
                }
                // long end = new Date().getTime();
                // log.info(this.taskName + " 完成，耗时:" + (end - start));
                jobSerivce
                        .execOverSystemJob(systemJob.getClassName(), isSuccess, result.getReturnValue().getRunCount());
            } else {
                log.info("任务[" + systemJob.getTaskName() + "]正在运行中...");
            }
        } else {
            log.info("任务[" + systemJob.getTaskName() + "]上次任务还没有完成,等下次执行");
            return;
        }
    }

    /**
     * <pre>
     * 具体业务执行
     * </pre>
     * 
     * @param isTimeout
     *            上次任务是否超时
     */
    public abstract void exec(boolean isTimeout, ScheduleConfig config);
}
